/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.lcm.metadata.api.entity;

import com.inspur.edp.lcm.metadata.api.IMdExtRuleContent;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 元数据实体

 */
@Data
public class GspMetadata
{
    /**
     元数据头节点，包含元数据ID、命名空间、名称等基础属性
     */
    private MetadataHeader header;

    /**
     元数据依赖关系节点
     */
    private List<MetadataReference> refs;

    /**
     元数据内容
     */
    private IMetadataContent content;

    /**
     * 扩展规则
     */
    private IMdExtRuleContent extendRule;
    /**
     元数据在元数据包中的相对路径
     设计时，该相对路径为纯路径信息，不带文件名及后缀
     打包时，该相对路径为带着文件名及后缀的相对完整路径信息
     */
    private String relativePath;

    /**
     扩展属性，如构件元数据又细分为服务端构件、客户端构件等，可以将具体类型存放到扩展属性中，获取到该属性后由各元数据自己解析扩展属性内容
     */
    private String extendProperty;

    /**
    是否为扩展的元数据
     */
    private boolean extended;

    /**
    此元数据内容的前一版本号，扩展场景下使用
     */
    private String previousVersion;

    /**
    元数据内容的当前版本号，扩展场景下使用
     */
    private String version;

    /**
     * 元数据属性
     */
    private MetadataProperties properties;

    public GspMetadata() {
    }

    public GspMetadata(MetadataHeader header, IMetadataContent content, String extendProperty, MetadataProperties properties) {
        this.header = header;
        this.content = content;
        this.extendProperty = extendProperty;
        this.properties = properties;
    }

    public GspMetadata(MetadataHeader header, String extendProperty, boolean extended, String previousVersion, String version, MetadataProperties properties) {
        this.header = header;
        this.extendProperty = extendProperty;
        this.extended = extended;
        this.previousVersion = previousVersion;
        this.version = version;
        this.properties = properties;
    }

    public GspMetadata(MetadataHeader header) {
        this.header = header;
    }

    public GspMetadata(MetadataHeader header, String extendProperty) {
        this.header = header;
        this.extendProperty = extendProperty;
    }

    public GspMetadata(MetadataHeader header, List<MetadataReference> refs, String extendProperty) {
        this.header = header;
        this.refs = refs;
        this.extendProperty = extendProperty;
    }

    /**
     * clone
     * */
    @Override
    public Object clone() {
        GspMetadata metadata = new GspMetadata();
        metadata.setHeader((MetadataHeader) this.header.clone());
//        metadata.setContent(null);
        metadata.setRelativePath(this.getRelativePath());
        metadata.setExtendProperty(this.getExtendProperty());
        metadata.setExtended(this.isExtended());
        metadata.setPreviousVersion(this.previousVersion);
        metadata.setVersion(this.version);
        metadata.setProperties(this.getProperties()==null?null:(MetadataProperties)this.getProperties().clone());
        metadata.setRefs(new ArrayList<>());
        if(this.refs == null || this.refs.size() <= 0)
            return metadata;
        else {
            this.refs.forEach(item -> {
                metadata.getRefs().add((MetadataReference) item.clone());
            });

            return metadata;
        }
    }

    @Override
    public boolean equals(Object obj){
        if (obj == null){
            return false;
        }
        if (obj instanceof GspMetadata){
            GspMetadata otherMetadata = (GspMetadata) obj;
            if ((this.getHeader().getId().equals(otherMetadata.getHeader().getId())) && compareStringValue(this.getHeader().getCertId(), otherMetadata.getHeader().getCertId()) ){
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode(){
        int result = 17;
        result = 31 * result + ( StringUtils.isEmpty(this.getHeader().getId()) ? 0 : this.getHeader().getId().hashCode());
        result = 31 * result + ( StringUtils.isEmpty(this.getHeader().getCertId()) ? 0 : this.getHeader().getCertId().hashCode());
        return result;
    }

    private boolean compareStringValue(String value1, String value2){
        if (StringUtils.isEmpty(value1) && StringUtils.isEmpty(value2)){
            return true;
        }
        else {
           if (StringUtils.isEmpty(value1) == false){
               return value1.equals(value2);
           }
           else{
               return false;
           }
        }
    }
}